# 1 cffi库使用

cffi库可以静态、动态调用c函数。为此它可以生成各种基础ffi库,进而衍生出更好用的库。

# 1.1 加载动态库

(import  (scheme) (cffi cffi)) ;;使用cffi库
(load-librarys "foo") ;;加载动态库,这里的foo是dll的名字,即库的扩展名为foo.dll或者foo.so默认地址在鸭库的bin目录下,当然也支持绝对地址。	

# 1.2 申明函数

c函数原型定义是这样的

char* foo_string_string(char *str){
  printf("foo_string_string\n");
  printf("foo_string_string =%p\n",str);
    printf("foo_string_string =%s\n",str);
    str[0]='e';
    str[1]='e';
    printf(" ==foo_string_string =%s\n",str);

    return str;
}

定义scheme函数

(def-function foo-string-string "foo_string_string" (string) string )

# 1.3 调用函数

调用函数

(foo-string-string "hello,world")

# 2 高级篇

cffi还有很多特性,可以操作内存、转换对象。

# 2.1 内存低级操作

cffi-alloc分配内存

(cffi-alloc 1024)

cffi-free释放内存

(define a (cffi-alloc 1024))
(cffi-free a)

cffi-get-string读取内存字符串、cffi-set-string 设置内存字符串值

(define str (cffi-alloc 1024))
(cffi-set-string str "hello,world")
(printf "~a" (cffi-get-string str))

# 2.2 c结构体使用

声明结构体定义

(def-struct A
  (c int  32 )
  (d double 64 )
  (i int  32 ) )

创建结构体

 (make-A 10 20.0 30 )
 (define a (make-A 10 20.0 30 ) )
 (display a) 
 (printf "sizeof=~a\n" (struct-size a))

# 2.3 结构体转scheme类型

struct2lisp这个函数可以c的结构体转换成lisp类型

(define a (make-A 10 20.0 30 ) )
(printf "struct1(a)=>~a\n" (struct1 a))
(define temp (cffi-alloc (struct-size a));;模拟c内存地址
(printf "struct2lisp ~a\n" (struct2lisp temp a))

# 2.4 scheme类型转结构体

lisp2struct这个函数可以转换成c的结构体

(define temp (lisp2struct a (cffi-alloc (struct-size a))))
(printf "lisp2struct ~a\n" temp)
Last Updated: 12/11/2020, 1:11:36 PM